package cn.edu.swu.miniwebsvr.handler;

import cn.edu.swu.miniwebsvr.core.Config;
import cn.edu.swu.miniwebsvr.core.Handler;
import cn.edu.swu.miniwebsvr.core.Parameter;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public class DefaultHandler implements Handler {
    @Override
    public void handle(Parameter request, OutputStream response) {
        PrintWriter writer = new PrintWriter(response);
        // TODO: [222024321072045/谢冈兵]
        // 获取请求路径（将 / 映射到 index.html）

        try {
        String requestPath = request.getUrl();
        if (requestPath.equals("/")) {
            requestPath = "/index.html";
        }
        // 根据 Config.getWebRoot() 构建完整文件路径
        Path filePath = Paths.get(Config.getInstance().getWebRoot(), requestPath.substring(1));


            if (Files.exists(filePath) && !Files.isDirectory(filePath) && isSafePath(filePath)) {
                byte[] fileBytes = Files.readAllBytes(filePath);

                // TODO: [222024321072045/谢冈兵] 确定并设置正确的 Content-Type (例如 text/html, image/jpeg 等)
                String contentType = determineContentType(filePath);

                // 写入 200 OK 响应头
                writer.println("HTTP/1.1 200 OK");
                writer.println("Content-Type: " + contentType);
                writer.println("Content-Length: " + fileBytes.length);
                writer.println("Connection: close");
                writer.println();
                writer.flush();

                // 写入文件内容
                response.write(fileBytes);
            } else {
                // 文件不存在或路径错误，返回 404
                String content = "<html><head><title>404 Not Found</title></head><body>" +
                        "<h1>404 Not Found</h1>" +
                        "<p>The requested resource " + request.getUrl() + " was not found.</p>" +
                        "</body></html>";

                writer.println("HTTP/1.1 404 Not Found");
                writer.println("Content-Type: text/html; charset=UTF-8");
                writer.println("Content-Length: " + content.getBytes().length);
                writer.println("Connection: close");
                writer.println();
                writer.println(content);
            }
        } catch (IOException e) {
            // TODO: [222024321072045/谢冈兵] 文件读取异常，返回 500 Internal Server Error
            String errorContent = "<html><head><title>500 Internal Server Error</title></head><body>" +
                    "<h1>500 Internal Server Error</h1>" +
                    "<p>Error reading file: " + e.getMessage() + "</p>" +
                    "</body></html>";

            writer.println("HTTP/1.1 500 Internal Server Error");
            writer.println("Content-Type: text/html; charset=UTF-8");
            writer.println("Content-Length: " + errorContent.getBytes().length);
            writer.println("Connection: close");
            writer.println();
            writer.println(errorContent);
        } finally {
            writer.flush();
        }
    }

    private String determineContentType(Path filePath) throws IOException {
        String fileName = filePath.getFileName().toString().toLowerCase();

        if (fileName.endsWith(".html") || fileName.endsWith(".htm")) {
            return "text/html; charset=UTF-8";
        } else if (fileName.endsWith(".css")) {
            return "text/css";
        } else if (fileName.endsWith(".js")) {
            return "application/javascript";
        } else if (fileName.endsWith(".png")) {
            return "image/png";
        } else if (fileName.endsWith(".jpg") || fileName.endsWith(".jpeg")) {
            return "image/jpeg";
        } else if (fileName.endsWith(".gif")) {
            return "image/gif";
        } else if (fileName.endsWith(".txt")) {
            return "text/plain; charset=UTF-8";
        } else {
            try {
                String detectedType = Files.probeContentType(filePath);
                return detectedType != null ? detectedType : "application/octet-stream";
            }catch (IOException e){
                return "application/octet-stream";
            }
        }
    }

    private boolean isSafePath(Path filePath) {
        // 安全检查：确保文件路径在webroot目录内
        Path webRoot = Paths.get(Config.getInstance().getWebRoot()).toAbsolutePath().normalize();
        Path normalizedPath = filePath.toAbsolutePath().normalize();
        return normalizedPath.startsWith(webRoot);
    }
}
